from fastapi import APIRouter, HTTPException, status, Request
from datetime import datetime, timedelta
from . import scheams, models
from applicaton.utils import wechat_tools,tools
from applicaton.utils.jwt_tool import JwtToken
from applicaton import settings
from tortoise.expressions import Q

app = APIRouter()


@app.post('/register', response_model=scheams.UserRegisterResponse)
async def register(request: Request, user_info: scheams.UserRegisterRequest):
    """处理用户注册请求"""
    # 1. 验证用户账号是否重复注册[mobile]
    user = await models.User.filter(mobile=user_info.mobile).first()
    if user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='当前手机已注册，不能重复注册！')

    # 判断验证码是否正确
    redis = request.app.state.redis
    redis_sms = await redis.get(f'sms_{user_info.mobile}')
    if redis_sms is None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='验证码已过期！')
    if redis_sms != user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='验证码不正确！')

    # 2. 通过小程序提交的code授权码到微信官方获取当前微信用户的openid和session_key
    wechat_user = wechat_tools.get_wechat_info(user_info.code)

    # 验证微信是否重复注册多个账号
    user = await models.User.filter(openid=wechat_user['openid']).first()
    if user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='当前微信已绑定其他账号，不能重复注册！')

    # 3. 添加用户数据
    user = await models.User.create(
        **dict(user_info),
        username=user_info.mobile,
        avatar=user_info.avatarUrl,
        nickname=user_info.nickName,
        sex=user_info.gender,
        openid=wechat_user['openid']
    )

    # 创建jwt
    token = JwtToken.create_token({
        'id': user.id
    })

    # 保存Token到redis中
    await redis.setex(f'token_{user.id}', settings.JWT['expire_time'], token)

    # 删除redis中保存的验证码，防止一码多用
    await redis.delete(f'sms_{user_info.mobile}')

    # 4. 返回结构
    return {
        'id': user.id,
        'nickname': user.nickname,
        'avatar': user.avatar,
        'code': status.HTTP_200_OK,
        'err_msg': '用户注册成功',
        'status': 'Success',
        'token': token,
    }


@app.post('/login', response_model=scheams.UserRegisterResponse)
async def login(request: Request, user_info: scheams.UserLoginRequest):
    """用户登录操作"""
    # 判断验证码是否正确
    redis = request.app.state.redis
    redis_sms = await redis.get(f'sms_{user_info.mobile}')
    if redis_sms is None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='验证码已过期！')
    if redis_sms != user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='验证码不正确！')

    # 判断当前用户是否存在
    # 1. 基于code请求微信服务器获取用户的OpenID以及将来调用用户信息的session_key
    result = wechat_tools.get_wechat_info(user_info.code)

    # 0. 根据手机号或微信OpenID判断当前账号是否已经注册过
    user = await models.User.filter(Q(mobile=user_info.mobile) | Q(openid=result['openid'])).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='当前用户不存在！')

    # 判断密码是否正确
    hashing = tools.Hashing()
    ret = hashing.verify(user_info.password, user.password)
    if not ret:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='当前账号或密码错误！')

    # 生成token
    token = JwtToken.create_token({
        'id': user.id
    })

    # 记录用户的登陆历史
    await models.UserLoginHistory.create(user=user)

    # 保存Token到redis中
    await redis.setex(f'token_{user.id}', settings.JWT['expire_time'], token)

    # 如果打开限流功能，则初始化用户每天免费使用AI助理的次数到redis中，次日过期
    if settings.AI_ROBOT['limit'] == '1' and not redis.get(f'api_{user.id}'):
        current_time = datetime.now()
        tomorrow = current_time + timedelta(days=1)
        tomorrow_zero = datetime.strptime(f'{tomorrow.year}-{tomorrow.month}-{tomorrow.day}', '%Y-%m-%d')
        delta = tomorrow_zero - current_time
        # 用户登陆时，记录当前可以免费使用AI助理的次数存储于redis
        redis.setex(f'api_{user.id}', delta.seconds, settings.AI_ROBOT['count'])

    # 删除redis中保存的验证码，防止一码多用
    await redis.delete(f'sms_{user_info.mobile}')

    # 返回响应数据
    return {
        'id': user.id,
        'nickname': user.nickname,
        'avatar': user.avatar,
        'code': status.HTTP_200_OK,
        'err_msg': '用户登陆成功',
        'status': 'Success',
        'token': token,
    }
